package com.witframework.web.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.witframework.PropertiesConstants;
import com.witframework.WitException;
import com.witframework.baseapp.security.UserSession;
import com.witframework.core.ApplicationProperties;

/**
 * this class loads the frameworks, javascript files and css files from the jar
 * file changes to the javascript or css files can only be done by repacking the
 * jar
 *
 */
public final class FileLoader extends GenericServlet {
	private static Log log = LogFactory.getLog(FileLoader.class);	
	
	private String [] securityURIs;
	/**
	 * this is the base where we can find the source wich sould be loaded
	 */
	private String baseFolder = null;
	/**
	 * write the content from the jarfile to the client stream use
	 * bufferedwriter to handel newline the filename is found in the requestURI
	 * the contextpath is excluded and replaced with the base package name
	 */
	@Override
	public void service(ServletRequest req0, ServletResponse resp0)
			throws ServletException, IOException {
		
		HttpServletResponse response = (HttpServletResponse) resp0;
		HttpServletRequest request = (HttpServletRequest) req0;
		
		String uri = request.getRequestURI();	
		String prefix=null;
		String resourceUri = uri.substring(request.getContextPath().length());
		if(uri.indexOf(":")>0){
			prefix=resourceUri.substring(0,resourceUri.indexOf(":")+1);
		}
		String filepath="";
		if (prefix != null && resourceUri.startsWith(prefix)) {
			resourceUri = resourceUri.substring(prefix.length());
			filepath =  resourceUri;
		}
		filepath=java.net.URLDecoder.decode(filepath,"utf-8");
		UserSession us=(UserSession)request.getSession().getAttribute("UserSession");
		boolean needLogin=false;
		if(us==null||us.getUser().getId().equals("_GUEST_USER_TEMP_00")){			
			for(String securityURi:securityURIs){
				if(filepath.indexOf(securityURi)>=0){
					needLogin=true;
					break;
				}					
			}
		}
		if(needLogin){
			request.getSession().invalidate();
			toLogin(request,response);
		}else if(StringUtils.isNotEmpty(filepath)){
				OutputStream stream= response.getOutputStream();
				InputStream in=null ;
				if(StringUtils.isNotEmpty(baseFolder)&&prefix!=null){
					try{
						in=new java.io.FileInputStream(baseFolder+filepath);
					}catch(Exception e){
						throw new WitException("请求的文件未找到.");
					}
				}else{
					URL resourceURL=this.getClass().getResource(filepath);
					if(resourceURL==null){
						log.warn("resource not found (" + filepath + ")");
					}else{	
						try{
							if(resourceURL.getProtocol().equals("file"))
								in=new java.io.FileInputStream(java.net.URLDecoder.decode(resourceURL.getPath(),"utf-8").replace(resourceURL.getProtocol()+":",""));
							else
								in = this.getClass().getResourceAsStream(filepath);
						}catch(Exception e){
							throw new WitException("请求的文件未找到。");
						}
						
						
					}
				}
				if(in!=null){
					String strContentTemp = null;
					if (request.getParameter("download")!=null) {
						strContentTemp = "attachment;";
						response.setContentType("application/x-msdownload");
					} else {
						strContentTemp = "inline;";
					}
					String charset=request.getParameter("charset");
					String filename=request.getParameter("filename");
					if(null!=filename){
						if (null != charset) {
							String strFileNameTemp = new String(filename.getBytes(),"UTF-8");
							strContentTemp = strContentTemp + "filename=" + strFileNameTemp;
						} else {
							strContentTemp = strContentTemp + "filename=" + filename;
						}
					}
					response.setHeader("Content-Disposition", strContentTemp);
					
					response.setContentLength(in.available());
					byte[] buffer = new byte[10240];
					int len = -1;
					while ((len = in.read(buffer)) != -1) {					
						stream.write(buffer, 0, len);						
					}
				}else{
					throw new ServletException("请求的文件未找到(" + filepath + ").");
				}	
		}
	}
	@Override
	public void init() throws ServletException {		
		baseFolder = ApplicationProperties.getProperty(PropertiesConstants.FILE_UPLOAD_FOLDER);
		String security_folder=ApplicationProperties.getProperty(PropertiesConstants.SECURITY_FILE_UPLOAD_FOLDER);
		if(StringUtils.isNotEmpty(security_folder))
			securityURIs=StringUtils.split(security_folder,",");
	}
	public static String trim2Null(String str) {
		if (str != null && str.trim().length() > 0) {
			return str;
		}
		return null;
	}
	private void toLogin(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
		String target=response.encodeURL(request.getRequestURI()+(request.getQueryString()!=null?"?"+request.getQueryString():""));
		if(request.getSession().getAttribute("target")==null&&!request.getRequestURI().endsWith("loginController"+ApplicationProperties.getProperty(PropertiesConstants.WIT)))
			request.getSession().setAttribute("target",target);
		request.getRequestDispatcher(request.getContextPath()+ "/loginController"+ApplicationProperties.getProperty(PropertiesConstants.WIT)).forward(request,response);
		
	}
	
}
